Package gri.gridp.tasks

Source Code of gri.gridp.tasks.RunScriptTask$TaskController

/*
* File: RunProgramTask.java
* Author: Daniel Rogers
* Created on Jan 16, 2008
*
*/
package gri.gridp.tasks;

import gri.tasks.Task;
//import gri.tasks.AsyncTask;
import gri.tasks.AsyncTaskController;
import gri.tasks.AbstractTaskController;
import gri.tasks.AsyncEventHandler;

import dan.util.process.ExecutionContext;

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

import java.io.File;

import org.apache.log4j.Logger;

import gri.tasks.ParameterDef;
import gri.tasks.TaskDef;

import gri.data.DataType;
import gri.data.Types;

/**
* Wrapper around a ScriptExecutor which exposes it as a task.  This will
* involve the following inputs/outputs:
*   Inputs:
*     script  (string)
*     jobout  (fileName/string) ["stdout.txt"]
*     joberr  (fileName/string) ["stderr.txt"]
*     workdir (file)            [current workdir]
*   Outputs:
*     script      (file)
*     exitcode    (int)
*     jobout      (file)
*     joberr      (file)
*     outputFiles (file list)
*
* TODO: AsyncTask support is functional.  However, we don't really
*       have a way to know when the script finishes (besides polling
*       it) and thus can't call AsyncEventHandler when we finish.
*       We might need to re-think the event handler.
*    
* @author dan.rogers
*/
public class RunScriptTask implements Task { //, AsyncTask {
 
  static Logger logger = Logger.getLogger(RunScriptTask.class);

  // -------------------------------------------------------- Properties
 
  String scriptFile;
  String execCmd;
  boolean deleteWorkdirWhenFreed;
 
  // ------------------------------------------------------ Constructors
 
  public RunScriptTask(String scriptFile, String execCmd) {
    this.scriptFile = scriptFile;
    this.execCmd = execCmd;
    this.deleteWorkdirWhenFreed = false;
  }
 
  // --------------------------------------------------------- Accessors
 
  public void setScriptFile(String fileName) {
    this.scriptFile = fileName;
  }
  public String getScriptFile()          {return scriptFile;}
 
  public void setExecCommand(String cmd) {
    this.execCmd = cmd;
  }
  public String getExecCommand()          {return execCmd;}
 
  /**
   * Sets a flag indicating whether the working directory should be
   * deleted when the job is freed. (default = false)
   *
   * NOTE: An added safety feature exists that will not allow you to
   *       delete the default directory "." under any circumstances.
   */
  public void setDeleteDirectoryWhenFreed(boolean value) {
    this.deleteWorkdirWhenFreed = value;
  }
  public boolean isDeleteDirectoryWhenFreed()  {
    return this.deleteWorkdirWhenFreed;
  }
 
  // ---------------------------------------------------- Implementation
 
  public TaskDef getTaskDef() {
    return TASK_DEF;
  }
 
  public Map execute(Map inputs) throws Exception {
    ScriptExecutor executor = createScriptExecutor(inputs);
   
    if (logger.isDebugEnabled())
      logger.debug("Script executing...");
   
    ExecutionContext ctx = executor.start();
    ctx.waitForExit();

    if (logger.isDebugEnabled())
      logger.debug("Script execution complete: populating outputs");

    Map outputs = getOutputs(executor, ctx);

    if (logger.isDebugEnabled())
      logger.debug("Script outputs: " + Util.toString(outputs));
   
    return outputs;
  }
 
  public AsyncTaskController start(Map inputs, AsyncEventHandler handler) throws Exception {
    ScriptExecutor executor = createScriptExecutor(inputs);
   
    TaskController controller = new TaskController(executor);
    controller.start();
   
    return controller;
  }
 
  /**
   * Creates a ScriptExecutor that is configured with the given input
   * parameters.
   */
  protected ScriptExecutor createScriptExecutor(Map inputs) {
    ScriptExecutor executor = new ScriptExecutor(scriptFile, execCmd);
   
    Iterator iEntries = inputs.entrySet().iterator();
    Map.Entry entry;
    while (iEntries.hasNext()) {
      entry = (Map.Entry)iEntries.next();
     
      String name = (String)entry.getKey();
      Object value = entry.getValue();
     
      if (name.equals(SCRIPT))
        executor.setScript((String)value);
      else if (name.equals(STDOUT_FILE))
        executor.setOutputFileName((String)value);
      else if (name.equals(STDERR_FILE))
        executor.setErrorFileName((String)value);
      else if (name.equals(WORKDIR))
        executor.setWorkingDirectory((File)value);
      else
        logger.warn("Skipping unkown parameter: " + name);
    }
   
    return executor;
  }
 
  /**
     * Populates the output map with output values.  Output parameters
     * from the class are hard-coded while those indicated by the GRIDP
     * function are obtained by examining the working directory and
     * applying a FileMatcher to discover indicated files.
     */
    protected static Map getOutputs(ScriptExecutor executor, ExecutionContext ctx) {
        Map outputs = new HashMap();
       
        //exit code:
        int exitCode = ctx.getExitCode();
        outputs.put("exitcode", new Integer(exitCode));
       
        //script, stdout, and stderr files (if they exist):
        File script = executor.getScriptFile();
        if (!script.exists())
            script = null;
       
        File jobout = executor.getOutputFile();
        if (!jobout.exists())
            jobout = null;
       
        File joberr = executor.getErrorFile();
        if (!joberr.exists())
            joberr = null;
       
        outputs.put(SCRIPT, script);
        outputs.put(STDOUT_FILE, jobout);
        outputs.put(STDERR_FILE, joberr);
       
        //other files:
        File [] results = executor.getFileResults();
        List resultList = new ArrayList();
        for (int i=0; i<results.length; i++)
          resultList.add(results[i]);
       
        outputs.put(OUTPUT_FILES, resultList);
       
        return outputs;
    }
   
   
 
  // ----------------------------------------------------- AsyncController
 
   
  class TaskController extends AbstractTaskController {
   
    ScriptExecutor executor;
    ExecutionContext ctx;
    Map outputs = null;
   
    // Constructors:
   
    public TaskController(ScriptExecutor executor) {
      this.executor = executor;
    }
   
    // Implementation:
   
    public void start() throws Exception {
      this.ctx = executor.start();
    }
   
    public Map getOutputs() {
      if (isComplete()) {
        if (outputs == null)
          outputs = RunScriptTask.getOutputs(executor, ctx);
      }
      else
        throw new IllegalStateException("Process has not yet completed");
     
      return outputs;
    }
   
    public int getStatus() {
      return ctx.isComplete() ?
          COMPLETE : RUNNING;
    }
    public boolean isComplete() {
      return ctx.isComplete();
    }
   
    public void kill() {
      ctx.kill();
    }
   
    /*
    public void free() {
      if (this.deleteWorkdirWhenFreed) {
        File workdir = executor.getWorkingDirectory();
        if (!workdir.equals(new File("."))) {
          //this.workingDirectory.delete();
          Util.rmdir(workdir);
        }
      }
    }
    */
   
  }
 
 
  // ------------------------------------------------------------ TaskDef
   
  public static final String SCRIPT = "script";
  public static final String STDOUT_FILE = "jobout";
    public static final String STDERR_FILE = "joberr";
    public static final String WORKDIR = "workdir";
    public static final String EXIT_CODE = "exitcode";
    public static final String OUTPUT_FILES = "outputFiles";
 
    /**
     * TaskDef for a RunScriptTask
     */
    public static class RequestTaskDef extends TaskDef {
                       
        public RequestTaskDef(boolean useWorkdirParam) {           
            setInputs();
            setOutputs();
        }
        public RequestTaskDef() {
            this(false);
        }
       
        protected void setInputs() {
          ParameterDef script = new ParameterDef(SCRIPT, Types.STRING, "Text of script to execute");
            ParameterDef jobout = new ParameterDef(STDOUT_FILE, Types.STRING, "Name of the file for standard output");
            ParameterDef joberr = new ParameterDef(STDERR_FILE, Types.STRING, "Name of the file for standard error");
            ParameterDef workingDirectory = new ParameterDef(WORKDIR, Types.FILE, "Directory in which to execute script");
           
            script.setDisplayName("Script");
            jobout.setDisplayName("Standard Output File");
            joberr.setDisplayName("Standard Error File");
            workingDirectory.setDisplayName("Working Directory");
           
            jobout.setDefaultValue("stdout.txt");
            joberr.setDefaultValue("stderr.txt");
            workingDirectory.setDefaultValue(new File("."));
           
            addInput(script);
            addInput(jobout);
            addInput(joberr);
            addInput(workingDirectory);
        }
       
        protected void setOutputs() {
            ParameterDef exitCode = new ParameterDef(EXIT_CODE, Types.INTEGER, "Exit code returned by program");
            ParameterDef jobout = new ParameterDef(STDOUT_FILE, Types.FILE, "File containing standard output from the script");
            ParameterDef joberr = new ParameterDef(STDERR_FILE, Types.FILE, "File containing standard error from the script");
            ParameterDef script = new ParameterDef(SCRIPT, Types.FILE, "File containing the script that was executed");
           
            DataType FILE_LIST = Types.createListType(List.class, Types.FILE);
            ParameterDef outputFiles = new ParameterDef("outputFiles", FILE_LIST, "Output files");
           
            exitCode.setDisplayName("Exit Code");
            jobout.setDisplayName("Standard Output File");
            joberr.setDisplayName("Standard Error File");
            script.setDisplayName("Script File");
            outputFiles.setDisplayName("Output Files");
           
            addOutput(script);
            addOutput(jobout);
            addOutput(joberr);
            addOutput(exitCode);
            addOutput(outputFiles);
        }
       
    }
   
    public static final RequestTaskDef TASK_DEF = new RequestTaskDef();
   
}
TOP

Related Classes of gri.gridp.tasks.RunScriptTask$TaskController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.